#!usr/bin/env python  
# -*- coding:utf-8 _*-
""" 
@author:robot
@file: {TAPCLIENT}.py
@version:
@time: 2022/06/01 
"""
import inspect
import json
from pprint import pprint
from importlib import import_module

import fire

from TapClientCore.T01_init_conf.path_conf import PathConf
from TapClientCmd.util_print.connector_print import ConnectorPrint, os
from TapClientCmd.util_print.daas1 import DaaS1Print
from TapClientCore.T05_TM_feature.tapclient_api.tapclient_api_v1.tapclient_dataflow import V1TapclientDataflow
from TapClientCore.T05_TM_feature.tapclient_api.tapclient_api_v1.tapclient_datasource import V1TapclientDataSource

MODULE_SPLIT = '--'
SPLIT = '>'
TAPCLIENT = 'Tapclient'
CONNECTOR = 'Connect'
DAAS1 = 'DaaS1'
DAAS2 = 'DaaS2'
PDK = 'PDK'

DATASOURCE = 'DataSource'
DATAPIPELINE = 'DataPipeline'

EXIT = 'exit'
BACK = 'back'

python = 'python'
if os.name == 'posix':
    python = 'python376'

TAP_PATH = PathConf.TAP_CONNECTOR_PATH


class CmdStart:
    db_info_file = None
    db_info = None

    def __init__(self, db_info_file='db_info', serve=''):
        print('>init db_info and serve')
        self.db_info_file = db_info_file
        self.serve = serve
        if db_info_file == 'db_info':
            import db_info as _
        elif db_info_file == 'db_info_cloud':
            import db_info_cloud as _
        elif db_info_file:
            _ = import_module(f'TapDataSourceInfo.{db_info_file}')
        else:
            raise Exception('not found this file')
        self.db_info = _
        print(f'>db_info_file: {self.db_info_file}')
        print(f'>serve: {self.serve}')

    def start(self):
        T = TapClient(self.db_info_file, self.db_info, self.serve)
        T.main()


class TapClient(
    ConnectorPrint,
    DaaS1Print
):
    db_type = None
    db_type_list = None
    db_type_member = None
    current_dataflow_name = None
    current_dataflow_response = None

    def __init__(self, db_info_file, db_info, serve):
        self._serve = serve
        self.db_info = db_info_file
        self.db_type = self.get_classes(db_info)
        self.db_type_list = [k for k, v in self.db_type.items()]

    @staticmethod
    def help1():
        print('')
        print('Hi, you can use this module')
        print('')
        print(CONNECTOR)
        print(DAAS1)
        print(DAAS2)
        print(PDK)
        print('')
        print('-> use')
        print('<- back')
        print('exit')
        print('')
        print(f'example: use {CONNECTOR}')
        print('')

    @staticmethod
    def command_error(command):
        if command == '':
            return
        print('')
        print(f'Error: can not read command "{command}"')
        print('')

    @staticmethod
    def get_classes(arg):
        classes = {}
        cls_members = inspect.getmembers(arg, inspect.isclass)
        for name, _ in cls_members:
            classes.update({name: _})
        return classes

    # Connect
    def connector(self):
        self.connector_help1()
        while True:
            command2 = input(f"{TAPCLIENT}{MODULE_SPLIT}{CONNECTOR}{SPLIT}")
            if command2 == 'help':
                self.connector_help1()
            elif command2 == EXIT:
                raise InterruptedError
            elif command2 == BACK:
                break
            elif command2 == 'show_db_type':
                pprint(self.db_type)
            elif 'use ' in command2:
                command2 = self.use_replace(command2)
                if command2 not in self.db_type_list:
                    print(f'Error: not found "{command2}" db type')
                else:
                    self.connector_type(command2)
            else:
                self.command_error(command2)

    def connector_type(self, db_type):
        self.connector_help2()
        class_info = dir(self.db_type.get(db_type))
        self.db_type_member = []
        for i in class_info:
            if '__' not in i:
                self.db_type_member.append(i)
        while True:
            command3 = input(f"{TAPCLIENT}{MODULE_SPLIT}{CONNECTOR}{MODULE_SPLIT}{db_type}{SPLIT}")
            if command3 == 'help':
                self.connector_help1()
            elif command3 == EXIT:
                raise InterruptedError
            elif command3 == BACK:
                break

            elif command3 == 'show_member':
                pprint(self.db_type_member)
            elif 'use ' in command3:
                command3 = self.use_replace(command3)
                if command3 not in self.db_type_member:
                    print(f'Error: not found "{command3}" in db type "{db_type}"')
                else:
                    self.connector_type_db(db_type, command3)
            else:
                self.command_error(command3)

    def connector_type_db(self, db_type, db_name):
        self.connector_help3()
        while True:
            command4 = input(
                f"{TAPCLIENT}{MODULE_SPLIT}{CONNECTOR}{MODULE_SPLIT}{db_type}{MODULE_SPLIT}{db_name}{SPLIT}")
            if command4 == 'help':
                self.connector_help3()
            elif command4 == EXIT:
                raise InterruptedError
            elif command4 == BACK:
                break

            elif command4 == 'show_dbs':
                self.exec(
                    f'{python} {TAP_PATH} --db_info_file={self.db_info} --source_type={db_type} --name={db_name} {command4}')
            elif command4 == 'show_tables':
                self.exec(
                    f'{python} {TAP_PATH} --db_info_file={self.db_info} --source_type={db_type} --name={db_name} {command4}')
            elif command4 == 'show_tables_count':
                self.exec(
                    f'{python} {TAP_PATH} --db_info_file={self.db_info} --source_type={db_type} --name={db_name} {command4}')
            elif command4 == 'show_attr':
                self.exec(
                    f'{python} {TAP_PATH} --db_info_file={self.db_info} --source_type={db_type} --name={db_name} {command4}')
            elif 'use ' in command4:
                command4 = self.use_replace(command4)
                self.connector_type_db_table(db_type, db_name, command4)
            elif 'db.' in command4:
                if 'db.query(' in command4:
                    command4 = command4.replace('db.query(', '')[:-1]
                    self.exec(
                        f'{python} {TAP_PATH} --db_info_file={self.db_info} --source_type={db_type} --name={db_name} --sql="{command4}" query')
                elif 'db.exec(' in command4:
                    command4 = command4.replace('db.exec(', '')[:-1]
                    self.exec(
                        f'{python} {TAP_PATH} --db_info_file={self.db_info} --source_type={db_type} --name={db_name} --sql="{command4}" execute')
                else:
                    print('command can not read')
            else:
                self.command_error(command4)

    def connector_type_db_table(self, db_type, db_name, table):
        self.connector_help4()
        while True:
            command5 = input(
                f"{TAPCLIENT}{MODULE_SPLIT}{CONNECTOR}{MODULE_SPLIT}{db_type}{MODULE_SPLIT}{db_name}{MODULE_SPLIT}{table}{SPLIT}")
            if command5 == 'help':
                self.connector_help4()
            elif command5 == EXIT:
                raise InterruptedError
            elif command5 == BACK:
                break

            elif command5 == 'common_query':
                self.exec(
                    f'{python} {TAP_PATH} --db_info_file={self.db_info} --source_type={db_type} --name={db_name} --table={table} {command5}')

            elif command5 == 'common_count':
                self.exec(
                    f'{python} {TAP_PATH} --db_info_file={self.db_info} --source_type={db_type} --name={db_name} --table={table} {command5}')

            elif command5 == 'common_drop':
                self.exec(
                    f'{python} {TAP_PATH} --db_info_file={self.db_info} --source_type={db_type} --name={db_name} --table={table} {command5}')
            else:
                self.command_error(command5)

    def daas1(self):
        if self._serve:
            self.v1tm_datasource = V1TapclientDataSource({'serve': self._serve})
            self.v1tm_dataflow = V1TapclientDataflow({'serve': self._serve})
        if not self._serve:
            self.v1tm_datasource = V1TapclientDataSource()
            self.v1tm_dataflow = V1TapclientDataflow()
            self._serve = self.v1tm_datasource.v1tm.serve
        self.daas1_help1()
        while True:
            command2 = input(f"{TAPCLIENT}{MODULE_SPLIT}{DAAS1}{MODULE_SPLIT}{self._serve}{SPLIT}")
            command2 = self.use_replace(command2)
            if command2 == 'help':
                self.daas1_help1()
            elif command2 == EXIT:
                raise InterruptedError
            elif command2 == BACK:
                break
            elif 'DS.' in command2:
                command2 = command2.replace('DS.', '')
                try:
                    if 'load' in command2:
                        command2 = command2.replace('load(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        self.v1tm_datasource.tap_v1_datasource_load_schema(command2)
                    elif 'test(' in command2:
                        command2 = command2.replace('test(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        self.v1tm_datasource.tap_v1_datasource_test(command2)
                    elif 'remove(' in command2:
                        command2 = command2.replace('remove(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        self.v1tm_datasource.tap_v1_datasource_remove(command2)
                    elif 'query(' in command2:
                        command2 = command2.replace('query(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        pprint(self.v1tm_datasource.tap_v1_get_connections_by_name(command2))
                    elif 'show_db_type' in command2:
                        if command2 == 'show_db_type':
                            pprint(self.v1tm_datasource.tap_v1_get_all_connections_type())
                    elif "show_dbs" in command2:
                        if command2 == 'show_dbs':
                            pprint(self.v1tm_datasource.tap_v1_get_all_connections())
                        elif 'show_dbs.' in command2:
                            command2 = command2.replace('show_dbs.', '')
                            pprint(self.v1tm_datasource.tap_v1_get_connections_by_db_type(command2))
                    elif 'update(' in command2:
                        command2 = command2.replace('update(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                    elif 'create(' in command2:
                        command2 = command2.replace('create(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                    else:
                        self.command_error(command2)
                except Exception as E:
                    print(E)
            elif 'DF.' in command2:
                command2 = command2.replace('DF.', '')
                try:
                    if 'query(' in command2:
                        command2 = command2.replace('query(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        pprint(self.v1tm_dataflow.tap_v1_dataflow_get_by_name(command2))
                    elif 'cat_query(' in command2:
                        command2 = command2.replace('cat_query(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        pprint(self.v1tm_dataflow.tap_v1_cat_dataflow_get_by_name(command2))
                    elif 'cat_dataflows' in command2:
                        pprint(self.v1tm_dataflow.tap_v1_dataflow_get_all_dataflow_cat())
                    elif 'more_dataflows' in command2:
                        pprint(self.v1tm_dataflow.tap_v1_dataflow_get_all_dataflow_more())
                    elif 'clone.create(' in command2:
                        command2 = command2.replace('clone.create(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        command2 = command2.split('=')
                        name = command2[0]
                        setting = command2[1]
                        relation = command2[2]
                        table = command2[3]
                        source = command2[4]
                        target = command2[5]
                        _source = source.split('.')
                        _target = target.split('.')
                        source_info = getattr(
                            self.db_type.get(_source[0]),
                            _source[1]
                        )
                        target_info = getattr(
                            self.db_type.get(_target[0]),
                            _target[1]
                        )
                        self.current_dataflow_name = name
                        clone_config = {
                            'dag_name': 'clone',
                            'dataflow_config': {
                                'name': name,
                                'setting': setting,
                                'relation': relation,
                                'table': table,
                                'source': source_info,
                                'target': target_info
                            }
                        }
                        print(clone_config)
                        record = self.v1tm_dataflow.tap_v1_dataflow_create(clone_config)
                        self.current_dataflow_response = record
                    elif 'start(' in command2:
                        command2 = command2.replace('start(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        pprint(self.v1tm_dataflow.tap_v1_start_dataflow(command2))
                    elif 'stop(' in command2:
                        command2 = command2.replace('stop(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        pprint(self.v1tm_dataflow.tap_v1_stop_dataflow(command2))
                    elif 'delete(' in command2:
                        command2 = command2.replace('delete(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        self.v1tm_dataflow.tap_v1_dataflow_delete_by_name(command2)
                    elif 'stats(' in command2:
                        command2 = command2.replace('stats(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        pprint(self.v1tm_dataflow.tap_v1_get_dataflow_stats(command2))
                    elif 'reset(' in command2:
                        command2 = command2.replace('reset(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        self.v1tm_dataflow.tap_v1_reset_dataflow(command2)
                    # elif "show_dbs" in command2:
                    #     if command2 == 'show_dbs':
                    #         pprint(self.v1tm_dataflow.tap_v1_get_all_connections())
                    #     elif 'show_dbs.' in command2:
                    #         command2 = command2.replace('show_dbs.', '')
                    #         pprint(self.v1tm_dataflow.tap_v1_get_connections_by_db_type(command2))
                    else:
                        self.command_error(command2)
                except AttributeError as e:
                    pass
                except Exception as E:
                    pass
            elif command2 == CONNECTOR:
                self.connector()
            else:
                self.command_error(command2)

    def daas2(self):
        ...

    # pdk
    def pdk(self):
        while True:
            command2 = input(f"{TAPCLIENT}{MODULE_SPLIT}{PDK}{MODULE_SPLIT}{self._serve}{SPLIT}")
            if command2 == EXIT:
                raise InterruptedError
            elif command2 == BACK:
                break
            elif 'DataSource.' in command2:
                command2 = command2.replace('DataSource.', '')
                try:
                    if 'load_schema(' in command2:
                        command2 = command2.replace('load_schema(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        ...
                    elif 'query(' in command2:
                        command2 = command2.replace('query(', '')[:-1]
                        command2 = command2.replace('\'', '')
                        command2 = command2.replace('\"', '')
                        ...
                    elif "show_dbs" in command2:
                        if command2 == 'show_dbs':
                            ...
                        elif 'show_dbs.' in command2:
                            command2 = command2.replace('show_dbs.', '')
                            ...
                    else:
                        self.command_error(command2)
                except Exception as E:
                    print(E)
            elif 'DataPipeline.' in command2:
                ...
            else:
                self.command_error(command2)

    def main(self):
        self.help1()
        while True:
            try:
                command = input(f"{TAPCLIENT}{SPLIT}")
                command = self.use_replace(command)
                if command not in [
                    CONNECTOR,
                    DAAS1,
                    DAAS2,
                    PDK,
                    BACK,
                    EXIT,
                    'help',
                    ''
                ]:
                    if SPLIT in command:
                        path = []
                        _path = command.split(SPLIT)
                        for one in _path:
                            if one:
                                path.append(one)
                        path_one = path[0]
                        path_len = len(path)
                        if path_one == CONNECTOR:
                            if path_len == 1:
                                self.connector()
                            elif path_len == 2:
                                self.connector_type(path[1])
                            elif path_len == 3:
                                self.connector_type_db(path[1], path[2])
                            elif path_len == 4:
                                self.connector_type_db_table(path[1], path[2], path[3])
                            else:
                                print(f'{path} too long, can not goto')
                        elif path_one == DAAS1:
                            ...
                        elif path_one == DAAS2:
                            ...
                        elif path_one == PDK:
                            ...
                        else:
                            print('Error: command can not read')
                    else:
                        self.command_error(command)
                else:
                    if command == CONNECTOR:
                        self.connector()
                    elif command == DAAS1:
                        self.daas1()
                    elif command == DAAS2:
                        while True:
                            command2 = input(f"{TAPCLIENT}{MODULE_SPLIT}{DAAS2}{SPLIT}")
                            if command2 == BACK:
                                break
                    elif command == PDK:
                        self.pdk()
                    elif command == 'help':
                        self.help1()
                    elif command == EXIT:
                        raise InterruptedError
            except InterruptedError:
                print('')
                print('good bye !')
                break
            except Exception as E:
                print(E)
                raise E


if __name__ == '__main__':
    # 启动
    # python tapclient.py --db_info_file=db_info_v124 start
    fire.Fire(CmdStart)
